package com.brillilab.common.redis;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class RedisCache {

	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	/**
	 * 设置缓存
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean set(String key, Object value) {
		return set(key, value, null);
	}

	/**
	 * 设置缓存
	 *
	 * @param key
	 * @param value
	 * @param timeout 超时时间（秒）
	 * @return
	 */
	public boolean set(String key, Object value, Integer timeout) {
		try {
			if (timeout != null && timeout > 0) {
				redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
			} else {
				redisTemplate.opsForValue().set(key, value);
			}
			return true;
		} catch (Exception e) {
			log.error("Redis设置值异常：{}", e);
			return false;
		}
	}

	/**
	 * 获取单个值
	 *
	 * @param key
	 * @return
	 */
	public String get(String key) {
		return (String) getObj(key);
	}

	/**
	 * 获取Object
	 *
	 * @param key
	 * @return 成功返回value 失败返回null
	 */
	public Object getObj(String key) {
		return redisTemplate.opsForValue().get(key);
	}



	/**
	 * 删除redis中数据
	 *
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public void delete(String... key) {
		if (key != null && key.length > 0) {
			if (key.length == 1) {
				redisTemplate.delete(key[0]);
			} else {
				redisTemplate.delete(CollectionUtils.arrayToList(key));
			}
		}
	}

	/**
	 * 检测key是否存在
	 *
	 * @param key
	 * @return
	 */
	public Boolean exists(String key) {
		try {
			return redisTemplate.hasKey(key);
		} catch (Exception e) {
			log.error("Redis检测key是否存在异常：", e);
			return false;
		}
	}

	/**
	 * 获取Key失效时间
	 *
	 * @param key
	 * @return 时间(秒) 返回0代表为永久有效
	 */
	public Long getExpireTime(String key) {
		return redisTemplate.getExpire(key, TimeUnit.SECONDS);
	}

	/**
	 * 指定缓存失效时间
	 *
	 * @param key  键
	 * @param time 时间(秒)
	 * @return
	 */
	public boolean expire(String key, long time) {
		try {
			if (time > 0) {
				redisTemplate.expire(key, time, TimeUnit.SECONDS);
			}
			return true;
		} catch (Exception e) {
			log.error("Redis指定缓存失效时间异常：", e);
			return false;
		}
	}

	/**
	 * key所对应的value自增操作
	 * @auth  WuMenghao
	 * @date  2019-03-05
	 * @param key
	 * @param time
	 * @return
	 */
	public int incr(String key ,long time){
		RedisAtomicInteger counter = new RedisAtomicInteger(key,Objects.requireNonNull(redisTemplate.getConnectionFactory()));
		int rs=counter.getAndIncrement();
		if(time>0){
			counter.expire(time,TimeUnit.SECONDS);
		}
		return rs;
	}

	/**
	 * 匹配删除
	 * @param matchKey
	 * @return
	 */
	public void deleteByMatchKey(String matchKey) {
		Set<String> keys = redisTemplate.keys(matchKey);
		if (!CollectionUtils.isEmpty(keys)){
			redisTemplate.delete(keys);
		}
	}

	/**
	 * 匹配获取缓存数据
	 * @param matchKey
	 * @return
	 */
	public List<Object> getList(String matchKey) {
		List<Object> getList = new ArrayList<>();
		Set<String> keys = redisTemplate.keys(matchKey);
		if (!CollectionUtils.isEmpty(keys)){
            for (String key : keys) {
                getList.add(redisTemplate.opsForValue().get(key));
            }
		}
		return getList;
	}
}
